home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1995 August
/
CICA - The Ultimate Collection of Shareware for Windows (Disc 2) (August 1995).iso
/
disc2
/
programr
/
atre27.exe
/
ATREE_27
/
OCRDEMO2
/
OCRTRAIN.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-01
|
15KB
|
567 lines
/*****************************************************************************
**** ****
**** ocrtrain.cpp ****
**** ****
**** atree release 2.7 for Windows ****
**** Adaptive Logic Network (ALN) simulation program. ****
**** Copyright (C) M. Thomas, N. Sanche, W.W. Armstrong 1991, 1992 ****
**** ****
**** License: ****
**** A royalty-free license is granted for the use of this software for ****
**** NON_COMMERCIAL PURPOSES ONLY. The software may be copied and/or ****
**** modified provided this notice appears in its entirety and unchanged ****
**** in all derived source programs. Persons modifying the code are ****
**** requested to state the date, the changes made and who made them ****
**** in the modification history. ****
**** ****
**** Patent License: ****
**** The use of a digital circuit which transmits a signal indicating ****
**** heuristic responsibility is protected by U. S. Patent 3,934,231 ****
**** and others assigned to Dendronic Decisions Limited of Edmonton, ****
**** W. W. Armstrong, President. A royalty-free license is granted ****
**** by the company to use this patent for NON_COMMERCIAL PURPOSES to ****
**** adapt logic trees using this program and its modifications. ****
**** ****
**** Limited Warranty: ****
**** This software is provided "as is" without warranty of any kind, ****
**** either expressed or implied, including, but not limited to, the ****
**** implied warrantees of merchantability and fitness for a particular ****
**** purpose. The entire risk as to the quality and performance of the ****
**** program is with the user. Neither the authors, nor the ****
**** University of Alberta, its officers, agents, servants or employees ****
**** shall be liable or responsible in any way for any damage to ****
**** property or direct personal or consequential injury of any nature ****
**** whatsoever that may be suffered or sustained by any licensee, user ****
**** or any other party as a consequence of the use or disposition of ****
**** this software. ****
**** Modification history: ****
**** ****
**** 92.04.27 atree v2.5 for Windows, M. Thomas ****
**** 92.03.07 Release 2.6, Monroe Thomas, Neal Sanche ****
**** 92.01.08 Release 2.7, Monroe Thomas, Neal Sanche ****
**** ****
*****************************************************************************/
// ocrtrain.cpp
#include "ocr.h"
#include <edit.h>
void
TOcr::translate(HBITMAP hbm1, int dx, int dy)
{
HBITMAP hbm2;
BITMAP bm;
HDC hdc1 = CreateCompatibleDC(NULL);
HDC hdc2 = CreateCompatibleDC(NULL);
GetObject(hbm1, sizeof(BITMAP), (LPSTR)&bm);
hbm2 = CreateBitmap(bm.bmWidth * 2, bm.bmHeight * 2, bm.bmPlanes,
bm.bmBitsPixel, NULL);
SelectObject(hdc1, hbm1);
SelectObject(hdc2, hbm2);
SetStretchBltMode(hdc1, COLORONCOLOR);
SetStretchBltMode(hdc2, WHITEONBLACK);
StretchBlt(hdc2, 0 + dx, 0 + dy,
bm.bmWidth * 2,
bm.bmHeight * 2,
hdc1, 0, 0,
bm.bmWidth,
bm.bmHeight,
SRCCOPY);
StretchBlt(hdc1, 0, 0,
bm.bmWidth,
bm.bmHeight,
hdc2, 0, 0,
bm.bmWidth * 2,
bm.bmHeight * 2,
SRCCOPY);
DeleteDC(hdc1);
DeleteDC(hdc2);
DeleteObject(hbm2);
}
#define NOISEBITS (16*30)
void
TOcr::train(TrainStruct& ts)
{
PTDialog TrainSet;
PTBStatic TrainPct;
LPBIT_VEC training_set;
LPBIT_VEC desired;
char des[1];
WORD numsamples = ts.numsamples * 5;
float numdone = 0;
char szBuffer[8];
PTBitmap A[27];
PTBitmap L[27];
PTBitmap N[27];
WORD width = LetterBitmap->GetBytes(); //in bytes
WORD length = width * 8;
WORD numbits = .95 * length;
if (LetterBitmap->GetPlanes() != 1)
{
BWCCMessageBox(HWindow, "Need monochrome bitmaps!", "OCR Train", MB_OK);
exit(0);
}
TrainSet = new TDialog(this, OCR_TRAINSET);
TrainPct = new TBStatic(TrainSet, OCR_TRAINPCT, 8);
GetApplication()->MakeWindow(TrainSet);
UpdateWindow(HWindow);
HCURSOR hcursor = LoadCursor(NULL, IDC_WAIT);
hcursor = SetCursor(hcursor);
for (WORD i = 0; i < 3; i++)
{
A[i] = new TBitmap(ts.bitmaps[0]);
L[i] = new TBitmap(ts.bitmaps[1]);
N[i] = new TBitmap(ts.bitmaps[2]);
}
A[1]->Rotate(ts.maxrotation);
L[1]->Rotate(ts.maxrotation);
N[1]->Rotate(ts.maxrotation);
A[2]->Rotate(-ts.maxrotation);
L[2]->Rotate(-ts.maxrotation);
N[2]->Rotate(-ts.maxrotation);
for (i = 3; i < 27; i++)
{
A[i] = new TBitmap(A[i % 3]->GetBitmap());
L[i] = new TBitmap(L[i % 3]->GetBitmap());
N[i] = new TBitmap(N[i % 3]->GetBitmap());
}
for (i = 3; i < 24; i++)
{
int dx, dy;
if (i < 6)
{
dx = 0; dy = 1;
}
if (i < 9)
{
dx = 1; dy = 0;
}
if (i < 12)
{
dx = 1; dy = 1;
}
if (i < 15)
{
dx = 0; dy = -1;
}
if (i < 18)
{
dx = -1; dy = 0;
}
if (i < 21)
{
dx = -1; dy = -1;
}
if (i < 24)
{
dx = -1; dy = 1;
}
if (i < 27)
{
dx = 1; dy = -1;
}
translate(A[i]->GetBitmap(), dx, dy);
translate(L[i]->GetBitmap(), dx, dy);
translate(N[i]->GetBitmap(), dx, dy);
}
training_set = (LPBIT_VEC)farmalloc(sizeof(bit_vec) * numsamples);
MEMCHECK(training_set);
desired = (LPBIT_VEC)farmalloc(sizeof(bit_vec) * numsamples);
MEMCHECK(desired);
for (i = 0; i < numsamples; i++)
{
training_set[i].len = length;
training_set[i].bv = (LPSTR)farmalloc(width);
desired[i].bv = NULL;
}
SetCursor(hcursor);
UpdateWindow(HWindow);
// Grab a good A
A[0]->GetBits(training_set[0].bv);
des[0] = 1; // want 1 output
desired[0] = *(bv_pack(des,1));
// Grab a good L
L[0]->GetBits(training_set[1].bv);
des[0] = 0; // want 0 output
desired[1] = *(bv_pack(des,1));
// Grab a good N
N[0]->GetBits(training_set[2].bv);
des[0] = 0; // want 0 output
desired[2] = *(bv_pack(des,1));
numdone += 3;
// create training data
for (i = 1; i < ts.numsamples; i++)
{
/* allow multitasking during long loop! */
Windows_Interrupt(100);
if (shutdown || stop) break;
// Get an A
A[random(27)]->GetBits(training_set[i*3].bv);
des[0] = 1; // want 1 output
desired[i*3] = *(bv_pack(des,1));
for (WORD j = 0; j < numbits; j++)
{
bv_set(RANDOM(length), &(training_set[i*3]), RANDOM(2));
}
if (shutdown || stop) break;
// Get a L
L[random(27)]->GetBits(training_set[i*3 + 1].bv);
des[0] = 0; // want 0 output
desired[(i*3) + 1] = *(bv_pack(des,1));
for (j = 0; j < numbits; j++)
{
bv_set(RANDOM(length), &(training_set[i*3 + 1]), RANDOM(2));
}
if (shutdown || stop) break;
// Get a N
N[random(27)]->GetBits(training_set[i*3 + 2].bv);
des[0] = 0; // want 0 output
desired[(i*3) + 2] = *(bv_pack(des,1));
for (j = 0; j < numbits; j++)
{
bv_set(RANDOM(length), &(training_set[i*3 + 2]), RANDOM(2));
}
numdone += 3;
sprintf(szBuffer, "%% %4.2f", 100.0 * (numdone / numsamples));
TrainPct->SetText(szBuffer);
}
// Now reinforce on a white frame
if (!(shutdown || stop))
{
A[0]->GetBits(training_set[ts.numsamples * 3].bv);
des[0] = 0;
desired[ts.numsamples * 3] = *(bv_pack(des,1));
for (WORD j = 0; j < length; j++)
{
bv_set(j, &(training_set[ts.numsamples * 3]), 1);
}
numdone++;
}
for (i = (ts.numsamples * 3) + 1; i < (ts.numsamples * 4); i++)
{
if (shutdown || stop) break;
Windows_Interrupt(100);
// Get white frame
_fmemcpy(training_set[i].bv, training_set[ts.numsamples * 3].bv, width);
des[0] = 0; // want 0 output
desired[i] = *(bv_pack(des,1));
for (WORD j = 0; j < numbits; j++)
{
bv_set(RANDOM(length), &(training_set[i]), RANDOM(2));
}
numdone ++;
sprintf(szBuffer, "%% %4.2f", 100.0 * (numdone / numsamples));
TrainPct->SetText(szBuffer);
}
// Now reinforce on a black frame
if (!(shutdown || stop))
{
A[0]->GetBits(training_set[ts.numsamples * 4].bv);
des[0] = 0;
desired[ts.numsamples * 4] = *(bv_pack(des,1));
for (WORD j = 0; j < length; j++)
{
bv_set(j, &(training_set[ts.numsamples * 4]), 0);
}
numdone++;
}
for (i = (ts.numsamples * 4) + 1; i < (ts.numsamples * 5); i++)
{
if (shutdown || stop) break;
Windows_Interrupt(100);
// Get black frame
_fmemcpy(training_set[i].bv, training_set[ts.numsamples * 4].bv, width);
des[0] = 0; // want 0 output
desired[i] = *(bv_pack(des,1));
for (WORD j = 0; j < numbits; j++)
{
bv_set(RANDOM(length), &(training_set[i]), RANDOM(2));
}
numdone ++;
sprintf(szBuffer, "%% %4.2f", 100.0 * (numdone / numsamples));
TrainPct->SetText(szBuffer);
}
TrainSet->ShutDownWindow();
// Train tree
for (i = 0; i < ts.voters; i++)
{
if (shutdown || stop) break;
char szBuf[80];
LPATREE atree;
sprintf(szBuf,"Now training tree %d...", i + 1);
Status->SetText(szBuf);
EnableWindow(Stop->HWindow, FALSE);
atree = atree_create(length,ts.treesize);
int result = atree_train(atree, training_set, desired, 0, numsamples,
ts.mincorrect / 100 * numsamples,
ts.maxepochs, 1);
if (result != -1)
{
atree_fold(atree);
atree_write(ts.stream, atree);
}
else
{
stop = TRUE;
}
atree_free(atree);
EnableWindow(Stop->HWindow, TRUE);
}
Status->SetText("ALN Demo - Light flashes on under character ALN detects");
for (i = 0; i < 24; i++)
{
delete A[i];
delete L[i];
delete N[i];
}
if (shutdown) return;
// if shutdown is TRUE during training, then an exit has been requested
// we don't need to free the memory here, since Borland's memory
// manager will do that
for(WORD j = 0; j < numsamples; j++)
{
farfree(training_set[j].bv);
if (desired[j].bv != NULL)
{
farfree(desired[j].bv);
}
}
farfree(training_set);
farfree(desired);
}
void
TOcr::OcrTrain(RTMessage Msg)
{
EnableWindow(Start->HWindow, FALSE);
EnableWindow(Stop->HWindow, TRUE);
EnableWindow(Train->HWindow, FALSE);
EnableWindow(Reverse->HWindow, FALSE);
EnableWindow(Reset->HWindow, FALSE);
EnableWindow(Forget->HWindow, FALSE);
EnableWindow(EditA->HWindow, FALSE);
EnableWindow(EditL->HWindow, FALSE);
EnableWindow(EditN->HWindow, FALSE);
EnableMenuItem(hSysMenu, SC_CLOSE, MF_GRAYED);
Status->SetText("Retraining the ALN will take 15 - 30 minutes.");
BOOL opened = FALSE;
BOOL err = TRUE;
char szBuf[80];
HBITMAP tmp;
TrainStruct ts;
struct tagTransferBuf
{
char treesize[6];
char voters[3];
char numsamples[5];
char maxepochs[6];
char mincorrect[7];
char maxrotation[5];
} tb;
_CLASSDEF(TTrainDlg)
class TTrainDlg : public TDialog
{
public:
TTrainDlg::TTrainDlg(PTWindowsObject AParent, int ResourceId,
struct tagTransferBuf* ATransBuf)
: TDialog(AParent, ResourceId)
{
new TEdit(this, ID_TREESIZE, 6);
new TEdit(this, ID_VOTERS, 3);
new TEdit(this, ID_NUMSAMPLES, 5);
new TEdit(this, ID_MAXEPOCHS, 6);
new TEdit(this, ID_MINCORRECT, 7);
new TEdit(this, ID_MAXROTATION, 5);
TransferBuffer = ATransBuf;
}
};
// set default training values
ts.treesize = 2048;
ts.voters = 3;
ts.numsamples = 200;
ts.maxepochs = 30;
ts.mincorrect = 99.9;
ts.maxrotation = 5;
shutdown = FALSE;
stop = FALSE;
while (err)
{
err = FALSE;
itoa(ts.treesize, tb.treesize, 10);
itoa(ts.voters, tb.voters, 10);
itoa(ts.numsamples, tb.numsamples, 10);
itoa(ts.maxepochs, tb.maxepochs, 10);
sprintf(tb.mincorrect, "%5.2f", ts.mincorrect);
itoa(ts.maxrotation, tb.maxrotation, 10);
PTTrainDlg TrainDlg;
TrainDlg = new TTrainDlg(this, OCR_TRAINDLG, &tb);
if (GetApplication()->ExecDialog(TrainDlg) == IDCANCEL)
{
stop = TRUE;
break;
}
if ((ts.treesize = atoi(tb.treesize)) == 0)
{
err = TRUE;
BWCCMessageBox(HWindow, "Invalid Tree Size entry",
NULL, MB_ICONQUESTION | MB_OK);
}
if ((ts.voters = atoi(tb.voters)) == 0)
{
err = TRUE;
BWCCMessageBox(HWindow, "Invalid Voters entry",
NULL, MB_ICONQUESTION | MB_OK);
}
if ((ts.numsamples = atoi(tb.numsamples)) == 0)
{
err = TRUE;
BWCCMessageBox(HWindow, "Invalid Number of Samples entry",
NULL, MB_ICONQUESTION | MB_OK);
}
if ((ts.maxepochs = atoi(tb.maxepochs)) == 0)
{
err = TRUE;
BWCCMessageBox(HWindow, "Invalid Maximum Epochs entry",
NULL, MB_ICONQUESTION | MB_OK);
}
if ((ts.mincorrect = atof(tb.mincorrect)) == 0)
{
err = TRUE;
BWCCMessageBox(HWindow, "Invalid Minimum Percent Correct entry",
NULL, MB_ICONQUESTION | MB_OK);
}
ts.maxrotation = atoi(tb.maxrotation);
}
if (!(shutdown || stop))
{
if ((ts.stream = fopen("ocr.tre", "w")) == NULL)
{
BWCCMessageBox(HWindow, "Can't open 'ocr.tre'", "OCR Train",
MB_ICONEXCLAMATION | MB_OK);
exit(0);
}
atree_init(GetApplication()->hInstance, HWindow);
fprintf(ts.stream, "%d\n", ts.voters);
opened = TRUE;
}
if (!(shutdown || stop))
{
ts.bitmaps[0] = LetterA->GetBitmap();
ts.bitmaps[1] = LetterL->GetBitmap();
ts.bitmaps[2] = LetterN->GetBitmap();
Status->SetText("Please wait while training set is built for first character...");
train(ts);
}
if (!(shutdown || stop))
{
tmp = ts.bitmaps[0];
ts.bitmaps[0] = ts.bitmaps[1];
ts.bitmaps[1] = tmp;
Status->SetText("Please wait while training set is built for second character...");
train(ts);
}
if (!(shutdown || stop))
{
tmp = ts.bitmaps[0];
ts.bitmaps[0] = ts.bitmaps[2];
ts.bitmaps[2] = tmp;
Status->SetText("Please wait while training set is built for third character...");
train(ts);
}
if (opened)
{
fclose(ts.stream);
atree_quit();
}
if ((shutdown || stop) && opened) remove("ocr.tre");
EnableWindow(Start->HWindow, TRUE);
EnableWindow(Stop->HWindow, FALSE);
EnableWindow(Train->HWindow, TRUE);
EnableWindow(Reverse->HWindow, TRUE);
EnableWindow(Reset->HWindow, TRUE);
EnableWindow(Forget->HWindow, TRUE);
EnableWindow(EditA->HWindow, TRUE);
EnableWindow(EditL->HWindow, TRUE);
EnableWindow(EditN->HWindow, TRUE);
EnableMenuItem(hSysMenu, SC_CLOSE, MF_ENABLED);
}